///PHILOTES Source Code.  (C)2012 PhiloLabs
#pragma once

#ifndef _Archive_H__
#define _Archive_H__

#include "OgrePrerequisites.h"
#include "OgreString.h"
#include "OgreDataStream.h"
#include "OgreSharedPtr.h"
#include "OgreStringVector.h"
#include "core/exception.h"
#include <ctime>

namespace Ogre {

	
	
    
    struct FileInfo {
		/// The archive in which the file has been found (for info when performing
		/// multi-Archive searches, note you should still open through ResourceGroupManager)
		const Archive* archive;
        /// The file's fully qualified name
        String filename;
        /// Path name; separated by '/' and ending with '/'
        String path;
        /// Base filename
        String basename;
        /// Compressed size
        size_t compressedSize;
        /// Uncompressed size
        size_t uncompressedSize;
    };

    typedef vector<FileInfo>::type FileInfoList;
    typedef SharedPtr<FileInfoList> FileInfoListPtr;

    
	class _OgreExport Archive : public MemAlloc_General
    {
    protected:
        /// Archive name
        String mName; 
        /// Archive type code
        String mType;
		/// Read-only flag
		bool mReadOnly;
    public:


        
        Archive( const String& name, const String& archType )
            : mName(name), mType(archType), mReadOnly(true) {}

        
        virtual ~Archive() {}

		/// Get the name of this archive
		const String& getName(void) const { return mName; }

        /// Returns whether this archive is case sensitive in the way it matches files
        virtual bool isCaseSensitive(void) const = 0;

        
        virtual void load() = 0;

        
        virtual void unload() = 0;

		
		virtual bool isReadOnly() const { return mReadOnly; }

        
        virtual DataStreamPtr open(const String& filename, bool readOnly = true) const = 0;

		
		virtual DataStreamPtr create(const String& filename) const
		{
                        (void)filename;
			PHILO_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, 
				"This archive does not support creation of files.", 
				"Archive::create");
		}

		
		virtual void remove(const String& filename) const
		{
                        (void)filename;
			PHILO_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, 
				"This archive does not support removal of files.", 
				"Archive::remove");
		}

        
        virtual StringVectorPtr list(bool recursive = true, bool dirs = false) = 0;
        
        
        virtual FileInfoListPtr listFileInfo(bool recursive = true, bool dirs = false) = 0;

        
        virtual StringVectorPtr find(const String& pattern, bool recursive = true,
            bool dirs = false) = 0;

        
        virtual bool exists(const String& filename) = 0; 

		
		virtual time_t getModifiedTime(const String& filename) = 0; 


        
        virtual FileInfoListPtr findFileInfo(const String& pattern, 
            bool recursive = true, bool dirs = false) const = 0;

        /// Return the type code of this Archive
        const String& getType(void) const { return mType; }
        
    };
	
	

}

#endif
